/**
 * 
 */
package GUI;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.SpringLayout;
import javax.swing.border.EtchedBorder;

import Controleur.GestionnaireSimulateur;
import Controleur.ModeListener;
import Domaine.Noeud;
import Domaine.Reseau;
import Domaine.Segment;
import Erreurs.ChiffreInvalide;
import Simulateur.UrgencePlusAncienne;
import Simulateur.UrgencePlusProche;

import java.awt.event.*;
import java.util.ArrayList;

/**
 * @author Nicolas Messier
 *
 */
public class FenetrePrincipale extends JFrame
{
	/*
	 * 
	 * Attributs
	 *
	 */

	
	private static final long serialVersionUID = 666131359174482L;
	
	private static final int HAUTEUR_FENETRE  = 600;
	private static final int LARGUEUR_FENETRE = 800;
	
	public enum EtatClick {PLAY, RESET, PAUSE};
	private EtatClick cliqueSim;
	
	// Controlleur
	private GestionnaireSimulateur controlleur;
	// Grille Magn�tique servant � placer nos Noeud/Segments
	private GrilleMagnetique gridPane;

	// Layout pour l'organisation
	private SpringLayout layout;
	// Outils d'�ditions "Ajouter Noeuds" "AjouterChemins" ...
	private JToolBar outilsEdit;
	// Bouton d'ajout de noeud
	private JButton addNoeud;
	//bouton de deplacement du noeud
	private JButton moveNoeud;
	// Bouton d'ajout de segment
	private JButton addSegment;
	//boutton de supression d'arc
	private JButton delSegment;
	//bouton pour bouger un segment
	private JButton moveSegment;
	//boutom pour edition rapide
	private JButton fastEdit;
	//bouton pour edition de la vitesse
	private JButton speedEdit;
	//Affichage de la grille
	private JButton gridDisplay;
	

	//Simulation
	private JLabel modeLabel;
	private JLabel timeLabel;
	private JPanel simulationPanel;
	private JButton play;
	private JButton reset;
	private JButton pause;
	
	// Fen�tre d'information
	private JTable infosPos;
	private JTable infosName;
	private JTable infoDist;
	private JPanel infosPane;
	
	private FenetreImportation fenetreImportation;
	private JMenuBar menuBar;
	private JMenu menuFichier;
	private JMenu menuEdition;
	private JMenu menuOption;
	private JMenu menuAide;
	
	//Menu Fichier
	private JMenuItem nouveau;
	private JMenuItem quitter;
	private JMenuItem sauvegarder;
	private JMenuItem open;
	private JMenuItem stat;
	
	//Menu �dition
	private JMenuItem undo;
	private JMenuItem redo;
	private JMenuItem importer;

	
	//Menu option
	private JMenuItem propriete;
	
	//Menu Aide
	private JMenuItem version;
	
	//boutons radio
	private JRadioButton radio1;
	private JRadioButton radio2;
	private JRadioButton radio3;
	private JRadioButton radio4;
	private JPanel radioPanel;
	
	//affichage interface
	// Tableau contenant le nom est le type de l'objet selectionn�
	final String[] header1 = {"Name", "Type"};
	final Object[][] col1= new Object[1][2];
	// Tableau contenant les coordonn�es du noeud
	final String [] header2 = {"X", "Y"};
	Object[][] col2 = new Object[1][header1.length];
	// Tableau contenant la distance entre deux noeuds.
	final String[] header3 = {"Distance"};
	final Object[][] col3 = new Object[1][1];
	
	/*
	 * 
	 * M�thodes
	 * 
	 */
	
	
	//Constructeur
		public FenetrePrincipale(GestionnaireSimulateur c)
		{
			this.controlleur = c;
			
			// Cr�ation de l'interface graphique.
			this.createLayout();
			this.fenetreImportation = new FenetreImportation();
			this.build(); //On initialise la fen�tre
		}
		
		private void createLayout()
		{
			// C�ation d'un layout pour organiser les objets
			this.layout = new SpringLayout();
			Container contentPane = this.getContentPane();
			contentPane.setLayout(layout);
		}
		
		public void afficherVersion()
		{
			JOptionPane.showMessageDialog(this,null,"Version 1.0 2013-10-30",JOptionPane.NO_OPTION);
		}
		
		public float obtenirNouvelleVitesse()
		{
			String vitesse = JOptionPane.showInputDialog(this,"Veuillez indiquer la nouvelle vitesse :","Vitesse du v�hicule d'urgence",JOptionPane.OK_CANCEL_OPTION);
			try
			{
				return Integer.parseInt(vitesse);
			} catch (NumberFormatException e){
				return -1;
			}
	 
		}
		
		private void createToolBar()
		{
			this.outilsEdit = new JToolBar(JToolBar.VERTICAL);
			// Cr�ation des boutons
			this.addNoeud = new JButton("Noeud");
			this.moveNoeud = new JButton("D�placer Noeud");
			this.addSegment = new JButton("Segment");
			this.moveSegment = new JButton("D�placer Segment");
			this.delSegment = new JButton("Supprimer segment"); 
			this.fastEdit =  new JButton("�dition rapide");
			this.speedEdit =  new JButton("Vitesse du v�hicule d'urgence");
			this.gridDisplay = new JButton("Grille");
			
			this.outilsEdit.setFloatable(false);
			// Ajout des boutons dans la toolbox.
			this.outilsEdit.add(this.addNoeud);
			this.outilsEdit.add(this.moveNoeud);
			this.outilsEdit.add(this.addSegment);
			this.outilsEdit.add(this.moveSegment);
			this.outilsEdit.add(this.delSegment);
			this.outilsEdit.add(this.fastEdit);
			this.outilsEdit.add(this.speedEdit);
			this.outilsEdit.add(this.gridDisplay);
			// Ajout de la ToolBox dans le layout.
			this.getContentPane().add(this.outilsEdit);
			// Placement sur le JFrame
			this.layout.putConstraint(SpringLayout.WEST, this.outilsEdit, 5, SpringLayout.WEST, this.getContentPane());
			this.layout.putConstraint(SpringLayout.NORTH, this.outilsEdit, 5, SpringLayout.NORTH, this.getContentPane());
			
			this.speedEdit.addActionListener(new ActionListener(){
				// On passe en mode move noeud
				public void actionPerformed(ActionEvent arg0)
				{
					if (controlleur.getReseau().getVehiculeUrgence() != null)
					{
						float nouvelleRapidite = obtenirNouvelleVitesse();
						if (nouvelleRapidite != -1)
						{
							try 
							{
								gridPane.setundo_redo();
								controlleur.getReseau().getVehiculeUrgence().setVitesse(nouvelleRapidite);
							} catch (ChiffreInvalide e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
					}
				}
			});
			
			this.addNoeud.addActionListener(new ActionListener(){
				// On passe en mode AJOUT_NOEUD
				public void actionPerformed(ActionEvent arg0){
					controlleur.setMode(GestionnaireSimulateur.ModeEdition.AJOUT_NOEUD);
				}
			});
			
			this.moveNoeud.addActionListener(new ActionListener(){
				// On passe en mode move noeud
				public void actionPerformed(ActionEvent arg0){
					controlleur.setMode(GestionnaireSimulateur.ModeEdition.MOVE_NOEUD);
				}
			});
			
			this.addSegment.addActionListener(new ActionListener(){
				// On passe en mode AJOUT_SEGMENT
				public void actionPerformed(ActionEvent a){
					controlleur.setMode(GestionnaireSimulateur.ModeEdition.AJOUT_SEGMENT);
				}
			});
			
			this.delSegment.addActionListener(new ActionListener(){
				// On passe en mode AJOUT_SEGMENT
				public void actionPerformed(ActionEvent a){
					controlleur.setMode(GestionnaireSimulateur.ModeEdition.DEL_SEGMENT);
				}
			});
			
			this.moveSegment.addActionListener(new ActionListener(){
				// On passe en mode AJOUT_SEGMENT
				public void actionPerformed(ActionEvent a){
					controlleur.setMode(GestionnaireSimulateur.ModeEdition.MOVE_SEGMENT);
				}
			});
			
			this.fastEdit.addActionListener(new ActionListener(){
				// On passe en mode AJOUT_NOEUD
				public void actionPerformed(ActionEvent arg0){
					controlleur.setMode(GestionnaireSimulateur.ModeEdition.RAPID_EDIT);
				}
			});
			this.gridDisplay.addActionListener(new ActionListener(){
				
				public void actionPerformed(ActionEvent arg0){
					gridPane.setDisplayGrid(!gridPane.getDisplayGrid());
				}
			});
		}
		
		private void createMenu()
		{
			this.menuBar = new JMenuBar();
			this.menuFichier = new JMenu("Fichier");
			this.menuEdition = new JMenu("Edition");
			this.menuOption = new JMenu("Option");
			this.menuAide = new JMenu("Aide");
			
			//Menu Fichier
			this.nouveau = new JMenuItem("Nouveau");
			this.quitter = new JMenuItem("Quitter");
			this.sauvegarder = new JMenuItem("Enregistrer");
			this.open = new JMenuItem("Ouvrir");
			this.stat = new JMenuItem("Statistiques");
			
			//Menu �dition
			this.undo = new JMenuItem("Annuler");
			this.redo = new JMenuItem("Suivant");
			
			//Menu option
			this.propriete = new JMenuItem("Propri�t�s");
			
			//Menu Aide
			this.version = new JMenuItem("Version");
			this.importer = new JMenuItem("Importer");
			
			// Ajout de l'onglet Fichier
			this.menuBar.add(menuFichier);
		    // Ajout de l'onglet Edition
			this.menuBar.add(menuEdition);
			// Ajout de l'onglet Option
			this.menuBar.add(menuOption);
			// Ajout de l'onglet Aide
			this.menuBar.add(menuAide);
			
			// Ajout d'option dans chaque onglets menu.
			this.menuFichier.add(nouveau);
			this.menuFichier.add(open);
			this.menuFichier.add(sauvegarder);
			this.menuFichier.add(stat);
			this.menuFichier.addSeparator();
			this.menuFichier.add(quitter);
			
			this.menuEdition.add(undo);
			this.menuEdition.add(redo);
			this.menuEdition.addSeparator();
			this.menuEdition.add(importer);

			
			this.menuOption.add(propriete);
			
			this.menuAide.add(version);
			
			// D�finition des actions pour chaque option de chaque menu.
			quitter.addActionListener(new ActionListener()
			{
				public void actionPerformed(ActionEvent arg0)
				{
					System.exit(0);
				}	
			});
			
			nouveau.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent arg0) {
					
				}
			});
			
			undo.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent arg0) {
					gridPane.undo();
					gridPane.repaint();
					controlleur = gridPane.getControlleur();
				}
			});
			
			redo.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent arg0) {
					gridPane.redo();
					gridPane.repaint();
					controlleur = gridPane.getControlleur();
				}
			});
			
			sauvegarder.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent arg0) {
					
				}
			});
			
			open.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent arg0) {
					
				}
			});
			
			stat.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent arg0) {
					
					
					FenetreStatistique s = new FenetreStatistique(controlleur.getSimulation().get_listeStatistiques());
					s.setVisible(true);
					
				}
			});
			
			propriete.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent arg0) {
					
				}
			});
			
			version.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent arg0) 
				{
					//Afficher une fen�tre d'information sur la version
					afficherVersion();
				}
			});
			
			this.importer.addActionListener(new ActionListener() {
				
				public void actionPerformed(ActionEvent arg0)
				{
					// Spawn de la fen�tre d'import d'image.
					fenetreImportation.setVisible(true);
				}
			});
			
			// On attache la barre de menu � la fen�tre
			this.setJMenuBar(this.menuBar);
		}
		
		
		private void createGrid()
		{
			this.gridPane = new GrilleMagnetique(this.controlleur, 30, 40, this);
			this.getContentPane().add(this.gridPane);
			// Placement dans le layout
			this.layout.putConstraint(SpringLayout.WEST, this.gridPane, 5, SpringLayout.EAST, this.outilsEdit);
			this.layout.putConstraint(SpringLayout.EAST, this.gridPane, -5, SpringLayout.EAST, this.getContentPane());
			this.layout.putConstraint(SpringLayout.NORTH, this.gridPane, 5, SpringLayout.NORTH, this.getContentPane());
			this.layout.putConstraint(SpringLayout.SOUTH, this.gridPane, -5, SpringLayout.NORTH, this.infosPane);
			// Ajout d'une bordure.
			this.gridPane.setBorder(BorderFactory.createLoweredBevelBorder());
		}
		
		
		private void createInfoTab()
		{
			this.infosName = new JTable(col1, header1);
			this.infosPos = new JTable(col2, header2);
			this.infoDist = new JTable(col3, header3);
	        
	        this.infosPane = new JPanel();
	        // On ajoute le tableau graphiquement.
	        this.infosPane.setLayout(new BoxLayout(this.infosPane, BoxLayout.PAGE_AXIS));
	        this.infosPane.add(this.infosName.getTableHeader());
	        this.infosPane.add(this.infosName);
	        this.infosPane.add(this.infosPos.getTableHeader());
	        this.infosPane.add(this.infosPos);
	        this.infosPane.add(this.infoDist.getTableHeader());
	        this.infosPane.add(this.infoDist);
	        this.getContentPane().add(this.infosPane);

			this.layout.putConstraint(SpringLayout.SOUTH, this.infosPane, -5, SpringLayout.SOUTH, this.getContentPane());
			this.layout.putConstraint(SpringLayout.EAST, this.infosPane, -5, SpringLayout.EAST, this.getContentPane());
			this.layout.putConstraint(SpringLayout.WEST, this.infosPane, -200, SpringLayout.EAST, this.infosPane);

		}
		
		private void createSimulationPanel(){
			this.play = new JButton("Play");

			this.reset = new JButton("Reset");
			this.pause = new JButton("Pause");
			pause.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					controlleur.arreterSimulation();
					cliqueSim = EtatClick.PAUSE;
				}
			});
			this.timeLabel = new JLabel();
			this.simulationPanel = new JPanel();
			this.modeLabel = new JLabel("NONE", JLabel.CENTER);
			
			this.simulationPanel.setLayout(new BorderLayout());
			
			this.timeLabel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
			this.timeLabel.setPreferredSize(new Dimension(100, 25));
			this.modeLabel.setPreferredSize(new Dimension(100,30));
			this.modeLabel.setBorder(BorderFactory.createLoweredBevelBorder());

			// On ajoute et on place le Label du mode dans le layout du panel de simulation.
			this.simulationPanel.add(this.modeLabel, BorderLayout.SOUTH);
			this.simulationPanel.add(this.timeLabel, BorderLayout.NORTH);
			this.simulationPanel.add(this.play, BorderLayout.LINE_START);
			this.simulationPanel.add(this.pause, BorderLayout.CENTER);
			this.simulationPanel.add(this.reset, BorderLayout.LINE_END);

			// On ajoute au layout g�n�ral.
			this.getContentPane().add(this.simulationPanel);
			
			// Contrainte de placement dans la fen�tre
			this.layout.putConstraint(SpringLayout.WEST, this.simulationPanel, 0, SpringLayout.WEST, this.outilsEdit);
			this.layout.putConstraint(SpringLayout.SOUTH, this.simulationPanel, -5, SpringLayout.SOUTH, this.getContentPane());
			
			play.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					if (cliqueSim != EtatClick.PAUSE)
					{
						gridPane.playSim();
					}
					controlleur.demarrerSimulation();
					cliqueSim = EtatClick.PLAY;
				}
			});
			
			reset.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) 
				{
					controlleur.arreterSimulation();
					gridPane.resetSim();
					controlleur = gridPane.getControlleur();
					cliqueSim = EtatClick.RESET;
					controlleur.resetSimulation();
					gridPane.repaint();
					
				}
			});
			
			this.controlleur.addModeListener(new ModeListener(){
				
				public void modeChange(GestionnaireSimulateur.ModeEdition old, GestionnaireSimulateur.ModeEdition nouv){
					if(nouv == GestionnaireSimulateur.ModeEdition.NONE){
						modeLabel.setText("NONE");
					}
					if(nouv == GestionnaireSimulateur.ModeEdition.AJOUT_NOEUD){
						modeLabel.setText("AJOUT NOEUD");
					}
					if(nouv == GestionnaireSimulateur.ModeEdition.AJOUT_SEGMENT){
						modeLabel.setText("AJOUT SEGMENT");
					}
					if(nouv == GestionnaireSimulateur.ModeEdition.DEL_SEGMENT){
						modeLabel.setText("SUPPRIMER SEGMENT");
					}
					if(nouv == GestionnaireSimulateur.ModeEdition.MOVE_NOEUD){
						modeLabel.setText("D�PLACER NOEUD");
					}
					if(nouv == GestionnaireSimulateur.ModeEdition.MOVE_SEGMENT){
						modeLabel.setText("D�PLACER SEGMENT");
					}
					if(nouv == GestionnaireSimulateur.ModeEdition.RAPID_EDIT){
						modeLabel.setText("�DITION RAPIDE");
					}
				}
			});
			
		}		
		
		
		public void createRadioStrategieAttente()
		{
			this.radioPanel = new JPanel();
			this.radioPanel.setLayout(new BorderLayout());
		    ButtonGroup groupeDeBoutons = new ButtonGroup();
		
            radio1 = new JRadioButton("Retour au port d'attache");
            groupeDeBoutons.add(radio1);
          
            radio2 = new JRadioButton("Attente sur place");
            groupeDeBoutons.add(radio2);
            
            radio1.setSelected(true);
            
            this.radioPanel.add(radio1, BorderLayout.EAST);
			this.radioPanel.add(radio2, BorderLayout.WEST);

			// On ajoute au layout g�n�ral.
			this.getContentPane().add(this.radioPanel);
			
			// Contrainte de placement dans la fen�tre
			this.layout.putConstraint(SpringLayout.WEST, this.radioPanel, 250, SpringLayout.WEST, this.getContentPane());
			this.layout.putConstraint(SpringLayout.SOUTH, this.radioPanel, -80, SpringLayout.SOUTH, this.getContentPane());
			

			radio1.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) 
				{
					 Object source = e.getSource();
					              
		             if(source == radio1)
		             controlleur.modifierStrategieAttente(1);               
		             else
		             controlleur.modifierStrategieAttente(2);
				}
			});
			
			radio2.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) 
				{
					 Object source = e.getSource();
		              
		             if(source == radio2)
		             controlleur.modifierStrategieAttente(2);               
		             else
		             controlleur.modifierStrategieAttente(1);
				}
			});
  
		}
		
		public void createRadioStrategie()
		{
			this.radioPanel = new JPanel();
			this.radioPanel.setLayout(new BorderLayout());
		    ButtonGroup groupeDeBoutons = new ButtonGroup();
		
            radio3 = new JRadioButton("Urgence la plus proche");
            groupeDeBoutons.add(radio3);
          
            radio4 = new JRadioButton("Urgence la plus ancienne");
            groupeDeBoutons.add(radio4);
            
            radio4.setSelected(true);
            
            this.radioPanel.add(radio3, BorderLayout.EAST);
			this.radioPanel.add(radio4, BorderLayout.WEST);

			// On ajoute au layout g�n�ral.
			this.getContentPane().add(this.radioPanel);
			
			// Contrainte de placement dans la fen�tre
			this.layout.putConstraint(SpringLayout.WEST, this.radioPanel, 250, SpringLayout.WEST, this.getContentPane());
			this.layout.putConstraint(SpringLayout.SOUTH, this.radioPanel, -50, SpringLayout.SOUTH, this.getContentPane());
			

			radio3.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) 
				{
					 Object source = e.getSource();
					              
					 if(source == radio3)
			             controlleur.modifierStrategie(1);               
			             else
			             controlleur.modifierStrategie(2); 
				}
			});
			
			radio4.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) 
				{
					 Object source = e.getSource();
					              
		             if(source == radio4)
		             controlleur.modifierStrategie(2);               
		             else
		             controlleur.modifierStrategie(1); 
				}
			});
  
		}
		
		//m�thodes priv�es
		private void build()
		{
			//fenetre
			this.setTitle("Intervensim");
			this.setAlwaysOnTop(true);
			this.setBackground(new Color(125,100,75));
			this.setSize(LARGUEUR_FENETRE , HAUTEUR_FENETRE);
			this.setLocationRelativeTo(null);
			this.setResizable(true);
			this.setDefaultCloseOperation(EXIT_ON_CLOSE);
			this.setJMenuBar(menuBar);
			
			this.createMenu();
			this.createToolBar();
			this.createInfoTab();
			this.createGrid();
			this.createSimulationPanel();
			this.createRadioStrategieAttente();
			this.createRadioStrategie();
		}
			
}
